From: Keir Fraser Date: Thu, 31 Jan 2008 09:33:26 +0000 (+0000) Subject: vmx realmode: Emulate MSR accesses. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14341^2~26 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=2179dc47cf8d85b478a71da091ee44cdab12017b;p=xen.git vmx realmode: Emulate MSR accesses. Signed-off-by: Nitin A Kamble Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/hvm/vmx/realmode.c b/xen/arch/x86/hvm/vmx/realmode.c index b5952953c4..be74b85408 100644 --- a/xen/arch/x86/hvm/vmx/realmode.c +++ b/xen/arch/x86/hvm/vmx/realmode.c @@ -410,6 +410,52 @@ realmode_write_cr( return X86EMUL_OKAY; } +static int +realmode_read_msr( + unsigned long reg, + uint64_t *val, + struct x86_emulate_ctxt *ctxt) +{ + struct cpu_user_regs _regs = { .ecx = (uint32_t)reg }; + + if ( !vmx_msr_read_intercept(&_regs) ) + { + struct realmode_emulate_ctxt *rm_ctxt = + container_of(ctxt, struct realmode_emulate_ctxt, ctxt); + rm_ctxt->exn_vector = (uint8_t)__vmread(VM_ENTRY_INTR_INFO); + rm_ctxt->exn_insn_len = 0; + __vmwrite(VM_ENTRY_INTR_INFO, 0); + return X86EMUL_EXCEPTION; + } + + *val = ((uint64_t)(uint32_t)_regs.edx << 32) || (uint32_t)_regs.eax; + return X86EMUL_OKAY; +} + +static int +realmode_write_msr( + unsigned long reg, + uint64_t val, + struct x86_emulate_ctxt *ctxt) +{ + struct cpu_user_regs _regs = { + .edx = (uint32_t)(val >> 32), + .eax = (uint32_t)val, + .ecx = (uint32_t)reg }; + + if ( !vmx_msr_write_intercept(&_regs) ) + { + struct realmode_emulate_ctxt *rm_ctxt = + container_of(ctxt, struct realmode_emulate_ctxt, ctxt); + rm_ctxt->exn_vector = (uint8_t)__vmread(VM_ENTRY_INTR_INFO); + rm_ctxt->exn_insn_len = 0; + __vmwrite(VM_ENTRY_INTR_INFO, 0); + return X86EMUL_EXCEPTION; + } + + return X86EMUL_OKAY; +} + static int realmode_write_rflags( unsigned long val, struct x86_emulate_ctxt *ctxt) @@ -495,6 +541,8 @@ static struct x86_emulate_ops realmode_emulator_ops = { .write_io = realmode_write_io, .read_cr = realmode_read_cr, .write_cr = realmode_write_cr, + .read_msr = realmode_read_msr, + .write_msr = realmode_write_msr, .write_rflags = realmode_write_rflags, .wbinvd = realmode_wbinvd, .cpuid = realmode_cpuid, diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 7994af937d..05dba05116 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2315,7 +2315,7 @@ static int is_last_branch_msr(u32 ecx) return 0; } -static int vmx_do_msr_read(struct cpu_user_regs *regs) +int vmx_msr_read_intercept(struct cpu_user_regs *regs) { u64 msr_content = 0; u32 ecx = regs->ecx, eax, edx; @@ -2507,7 +2507,7 @@ extern bool_t mtrr_fix_range_msr_set(struct mtrr_state *v, extern bool_t mtrr_def_type_msr_set(struct mtrr_state *v, u64 msr_content); extern bool_t pat_msr_set(u64 *pat, u64 msr); -static int vmx_do_msr_write(struct cpu_user_regs *regs) +int vmx_msr_write_intercept(struct cpu_user_regs *regs) { u32 ecx = regs->ecx; u64 msr_content; @@ -2949,12 +2949,12 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) break; case EXIT_REASON_MSR_READ: inst_len = __get_instruction_length(); /* Safe: RDMSR */ - if ( vmx_do_msr_read(regs) ) + if ( vmx_msr_read_intercept(regs) ) __update_guest_eip(inst_len); break; case EXIT_REASON_MSR_WRITE: inst_len = __get_instruction_length(); /* Safe: WRMSR */ - if ( vmx_do_msr_write(regs) ) + if ( vmx_msr_write_intercept(regs) ) __update_guest_eip(inst_len); break; diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index ec03e75d9c..f15975a097 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -37,6 +37,8 @@ void vmx_do_no_device_fault(void); void vmx_cpuid_intercept( unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx); +int vmx_msr_read_intercept(struct cpu_user_regs *regs); +int vmx_msr_write_intercept(struct cpu_user_regs *regs); void vmx_wbinvd_intercept(void); void vmx_realmode(struct cpu_user_regs *regs); int vmx_realmode_io_complete(void);